package com.mzm.service;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.stereotype.Service;

import com.mzm.api.CategoryDto;
import com.mzm.api.MediaInfoDto;
import com.mzm.api.ProductInfoDto;
import com.mzm.api.RecommendationDto;
import com.mzm.dao.ProductInfoDao;
import com.mzm.dao.RecommendationDao;
import com.mzm.domain.Category;
import com.mzm.domain.MediaInfo;
import com.mzm.domain.ProductImageInfo;
import com.mzm.domain.ProductInfo;
import com.mzm.domain.Recommendation;

@Service("dtoConversions")
public class DtoConversions {

	private static final Logger logger = LoggerFactory.getLogger(DtoConversions.class);

	@Resource
	private RecommendationDao recommendationDao;

	@Resource
	private ProductInfoDao productInfoDao;

	@Required
	@Autowired
	public void setRecommendationDao(RecommendationDao recommendationDao) {
		this.recommendationDao = recommendationDao;
	}

	@Required
	@Autowired
	public void setProductInfoDao(ProductInfoDao productInfoDao) {
		this.productInfoDao = productInfoDao;
	}

	public List<ProductInfoDto> convertProductInfos(List<ProductInfo> infos) {
		List<ProductInfoDto> dtos = new ArrayList<>();
		for (ProductInfo productInfo : infos) {
			dtos.add(convert(productInfo));
		}
		return dtos;
	}

	public List<RecommendationDto> convertRecommendations(List<Recommendation> recommendations) {
		List<RecommendationDto> dtos = new ArrayList<>();
		for (Recommendation recommendation : recommendations) {
			dtos.add(convert(recommendation));
		}
		return dtos;
	}

	public ProductInfo convert(ProductInfoDto dto) {
		if (dto.getId() != null) {
			ProductInfo pi = productInfoDao.findById(dto.getId(), false);
			if (pi == null) {
				logger.warn("could not find ProductInfo with id={}", dto.getId());
				return null;
			}
			return pi;
		}
		ProductInfo pi = new ProductInfo();
		pi.setProductName(dto.getProductName());
		pi.setProductType(dto.getProductType());
		Set<String> imageUrls = dto.getUrls();
		Set<ProductImageInfo> imageInfos = new HashSet<ProductImageInfo>();
		for (String url : imageUrls) {
			ProductImageInfo imageInfo = new ProductImageInfo();
			imageInfo.setImageUrl(url);
			imageInfos.add(imageInfo);
		}
		pi.setImageInfos(imageInfos);
		return pi;
	}

	public Recommendation convert(RecommendationDto dto) {
		if (dto.getId() != null) {
			Recommendation r = recommendationDao.findById(dto.getId(), false);
			if (r == null) {
				logger.warn("could not find Recommendation with id={}", dto.getId());
				return null;
			}
			return r;
		}
		Recommendation r = new Recommendation();
		r.setContent(dto.getContent());
		r.setCurrency(dto.getCurrencyCode());
		r.setGrade(dto.getGrade());
		r.setGradeRange(dto.getGradeRange());
		r.setKeywords(dto.getKeywords());
		r.setPrice(dto.getPrice());
		r.setProductInfo(convert(dto.getProductInfo()));
		r.setRemarks(dto.getRemarks());
		r.setRecommenderName(dto.getRecommenderName());
		r.setSheetNumber(dto.getSheetNumber());
		return r;
	}

	public RecommendationDto convert(Recommendation r) {
		if (r == null)
			return null;
		RecommendationDto dto = new RecommendationDto();
		dto.setId(r.getId());
		dto.setContent(r.getContent());
		dto.setCurrencyCode(r.getCurrency());
		dto.setGrade(r.getGrade());
		dto.setGradeRange(r.getGradeRange());
		dto.setKeywords(new ArrayList<>(r.getKeywords()));
		dto.setMediaInfo(convert(r.getMediaInfo()));
		dto.setPrice(r.getPrice());
		dto.setProductInfo(convert(r.getProductInfo()));
		dto.setRecommenderName(r.getRecommenderName());
		dto.setRemarks(r.getRemarks());
		dto.setSheetNumber(r.getSheetNumber());
		return dto;
	}

	public MediaInfoDto convert(MediaInfo m) {
		if (m == null)
			return null;
		MediaInfoDto dto = new MediaInfoDto();
		dto.setId(m.getId());
		dto.setMediaType(m.getMediaType());
		dto.setName(m.getName());
		dto.setPeriodicityType(m.getPeriodicityType());
		return dto;
	}

	public ProductInfoDto convert(ProductInfo p) {
		return convert(p, false);
	}

	public ProductInfoDto convert(ProductInfo p, boolean initImageInfos) {
		if (p == null)
			return null;
		ProductInfoDto dto = new ProductInfoDto();
		dto.setId(p.getId());
		dto.setProductName(p.getProductName());
		dto.setProductType(p.getProductType());
		if (initImageInfos) {
			Set<String> urls = new HashSet<String>();
			Set<ProductImageInfo> imageInfos = p.getImageInfos();
			for (ProductImageInfo imageInfo : imageInfos) {
				urls.add(imageInfo.getImageUrl());
			}
			dto.setUrls(urls);
		}
		return dto;
	}

	public static CategoryDto convert(Category c) {
		if (c == null)
			return null;
		CategoryDto dto = new CategoryDto();
		dto.setId(c.getId());
		dto.setName(c.getName());
		dto.setParent(convert(c.getParent()));
		return dto;
	}

	public static List<CategoryDto> convert(List<Category> categories) {
		List<CategoryDto> dtos = new ArrayList<CategoryDto>();
		for (Category category : categories) {
			dtos.add(convert(category));
		}
		return dtos;
	}
}
